import rehypeRaw from 'rehype-raw'; // 支持html
import remarkGfm from 'remark-gfm'; // 支持删除线，表格等等
import remarkMath from 'remark-math'; // 支持数学表达式
import copy from 'copy-to-clipboard';
import { useMemo } from 'react';
import { saveAs } from 'file-saver';
import { Button, message } from 'antd';
import rehypeKatex from 'rehype-katex'; // 支持数学公式
import ReactMarkdown from 'react-markdown';
import SyntaxHighlighter from 'react-syntax-highlighter';
import { CodeProps } from 'react-markdown/lib/ast-to-react';
import { CopyOutlined, DownloadOutlined } from '@ant-design/icons';
import theme from './codeStyle';
import 'katex/dist/katex.min.css';

interface IProps {
  value: string;
}

// 代码组件
const CodeBlock = ({ inline, className, children, ...props }: CodeProps) => {
  const match = useMemo(
    () => /language-(\w+)/.exec(className || ''),
    [className],
  );
  // 复制到剪切板
  const copyToClipboard = (value: string) => {
    try {
      copy(value);
      message.success('已成功复制到剪切板');
    } catch (error) {
      message.error('复制失败，请重试');
    }
  };
  // 保存代码文件
  const saveFile = (value: string, language: string) => {
    try {
      saveAs(new Blob([value]), `code.${language}`);
    } catch (error) {
      message.error('保存失败，请重试');
    }
  };
  return (
    <>
      {/* 不是代码组件就展示原始的样式 */}
      {!inline && match ? (
        <div className='w-full rounded-md overflow-hidden'>
          <div className='w-full bg-[#1c2530] h-10 text-white flex justify-between items-center'>
            <div className='w-full text-white ml-3'>{match[1]}</div>
            <Button
              type='text'
              size='small'
              className='text-white'
              onClick={() => copyToClipboard(String(children))}>
              <span className='text-white'>
                <CopyOutlined className='mr-2' />
                复制代码
              </span>
            </Button>
            <Button
              type='text'
              size='small'
              className='text-white'
              onClick={() => saveFile(String(children), match[1] || 'js')}>
              <span className='text-white'>
                <DownloadOutlined className='mr-2' />
                下载代码
              </span>
            </Button>
          </div>
          <SyntaxHighlighter
            {...props}
            style={theme}
            language={match[1]}
            PreTag='div'>
            {String(children).replace(/\n$/, '')}
          </SyntaxHighlighter>
        </div>
      ) : (
        <code {...props} className={className}>
          {children}
        </code>
      )}
    </>
  );
};

// markdown渲染组件，后续扩展为markdown编辑器
const Markdown: React.FC<any> = ({ value }: IProps) => {
  return (
    <div>
      <ReactMarkdown
        remarkPlugins={[remarkMath, remarkGfm]}
        rehypePlugins={[rehypeKatex, rehypeRaw]}
        components={{
          code: CodeBlock,
        }}>
        {value}
      </ReactMarkdown>
    </div>
  );
};

export default Markdown;
